package classconverstation.cscl.ist.psu.edu.client;


import java.util.ArrayList;

import classconverstation.cscl.ist.psu.edu.client.messengers.Course;
import classconverstation.cscl.ist.psu.edu.client.services.LoginService;
import classconverstation.cscl.ist.psu.edu.client.services.LoginServiceAsync;

import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;

public class ChooseClass implements EntryPoint {

	private LoginServiceAsync loginServiceSvc = GWT.create(LoginService.class);
	ArrayList<Course> enrolledCourses;
	ArrayList<Course> pendingCourses;
	ArrayList<Course> allCourses;
	ListBox courseList;
	FlowPanel myCoursesPanel;
	FlexTable myCoursesTable;
	String uid;


	public void onModuleLoad() {
		myCoursesPanel = getMyCoursesPanel();
		this.getUserOpenID();	
		RootPanel.get("class_selection").add(myCoursesPanel);
	}

	private void getUserOpenID(){
		// Initialize the service proxy.
		if (loginServiceSvc == null) {
			loginServiceSvc = GWT.create(LoginService.class);
		}
		// Set up the callback object.
		AsyncCallback<String> callback = new AsyncCallback<String>() {
			public void onFailure(Throwable caught) {
				caught.printStackTrace();
			}

			public void onSuccess(String result) {
				if (result.indexOf(".NOTACTIVATED") > -1) {
					Window.Location.replace("./ActivationRequired.html");
					return;
				}
				uid = result;
				//Window.alert(uid);
				loadEnrolledCourses();
			}
		};
		loginServiceSvc.getUserOpenId(callback);
	}

	FlowPanel getMyCoursesPanel(){
		courseList = this.getClassListBox();
		FlowPanel fPanel = new FlowPanel();
		myCoursesTable = new FlexTable();
		myCoursesTable.addStyleName("center-table");
		Label heading = new Label("My Courses");
		heading.addStyleDependentName("chooseClass");
		myCoursesTable.setWidget(0, 0, heading);
		myCoursesTable.setWidth("400px");
		fPanel.add(myCoursesTable);
		return fPanel;

	}

	ListBox getClassListBox(){
		ListBox list = new ListBox();
		list.addStyleDependentName("center-ListBox");
		list.setWidth("400px");
		return list;
	}

	private void loadEnrolledCourses(){
		// Initialize the service proxy.
		if (loginServiceSvc == null) {
			loginServiceSvc = GWT.create(LoginService.class);
		}
		// Set up the callback object.
		AsyncCallback<ArrayList<Course>> callback = new AsyncCallback<ArrayList<Course>>() {
			public void onFailure(Throwable caught) {
				caught.printStackTrace();
				Log.debug("Error when getting the enrolled courses");
			}

			public void onSuccess(ArrayList<Course> enrolledCourses) {
				addCoursesToList(enrolledCourses);	
				//Window.alert("Enrolled Courses: "+ enrolledCourses.size());
				Log.debug("Enrolled Courses: "+ enrolledCourses.size());
				loadAllCourses();
			}
		};
		// Make the call to the stock price service.
		loginServiceSvc.getEnrolledCourses(uid, callback);
	}
	private void addCoursesToList(ArrayList<Course> courses){
		enrolledCourses = new ArrayList<Course>();
		for (int i = 0; i< courses.size(); i++){
			final Course temp = courses.get(i);
			enrolledCourses.add(temp);
			Button enter = new Button("Enter");
			Button enterForum = new Button("Got to the Forum");
			myCoursesTable.setWidget(i+1, 0, new Label(temp.getCourseName()));
			myCoursesTable.setWidget(i+1, 1, enter);
			myCoursesTable.setWidget(i+1, 2, enterForum);
			enter.addClickHandler(new ClickHandler(){

				public void onClick(ClickEvent event) {
					int cid = temp.getCourseID();
					String cname = temp.getCourseName();

					Window.Location.replace("/classconversation/secured/ClassCommons.html?cid="+cid+"&cname="+cname);
					//					Window.Location.replace("/secured/ClassCommons.html?cid="+cid+"&cname="+cname);

				}

			});
			enterForum.addClickHandler(new ClickHandler(){

				public void onClick(ClickEvent event) {
					int cid = temp.getCourseID();
					String cname = temp.getCourseName();

					Window.Location.replace("/classconversation/secured/CCForum.html?cls="+cid+"&cname="+cname);
					//					Window.Location.replace("/secured/ClassCommons.html?cid="+cid+"&cname="+cname);

				}

			});
		}
	}

	private void loadAllCourses(){
		// Initialize the service proxy.
		if (loginServiceSvc == null) {
			loginServiceSvc = GWT.create(LoginService.class);
		}
		// Set up the callback object.
		AsyncCallback<ArrayList<Course>> callback = new AsyncCallback<ArrayList<Course>>() {
			public void onFailure(Throwable caught) {
				caught.printStackTrace();
				Log.debug("Error when getting all the courses");
			}

			public void onSuccess(ArrayList<Course> allCoursesFromDB) {
				allCourses = allCoursesFromDB;
				//Window.alert("All Courses: "+allCourses.size());
				loadCourseForApproval(uid);
			}
		};
		// Make the call to the stock price service.
		loginServiceSvc.getAllCourses(callback);
	}

	private void loadCourseForApproval(String userid){
		// Initialize the service proxy.
		if (loginServiceSvc == null) {
			loginServiceSvc = GWT.create(LoginService.class);
		}
		// Set up the callback object.
		AsyncCallback<ArrayList<Course>> callback = new AsyncCallback<ArrayList<Course>>() {
			public void onFailure(Throwable caught) {
				caught.printStackTrace();
				Log.debug("Error when getting the courses waiting for approval");
			}

			public void onSuccess(ArrayList<Course> courseForApproval) {
				pendingCourses = courseForApproval;
				//Window.alert("Pending Courses: "+pendingCourses.size());
				constructRequestingCoursePanel();

			}
		};
		loginServiceSvc.getCoursesForApproval(userid, callback);
	}

	private void constructRequestingCoursePanel(){
		FlowPanel requestClassPanel = getAvailabelClassPanel();
		RootPanel.get("available_classes").add(requestClassPanel);
	}

	FlowPanel getAvailabelClassPanel(){
		FlowPanel fPanel = new FlowPanel();
		FlexTable fTable = new FlexTable();
		fTable.addStyleName("center-table");
		Label heading = new Label("All Available Classes");
		heading.addStyleDependentName("chooseClass");
		fTable.setWidget(0, 0, heading);

		fTable.setWidget(1, 0, courseList);
		for (int i=0; i< this.allCourses.size();i++){
			courseList.addItem(allCourses.get(i).getCourseName());
		}
		Button enter = new Button("Join");
		enter.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				Course selectedCourse = getSelectedCourse();
				if (!isEnrolled(selectedCourse)){
					markAsEnrolled(selectedCourse);
				}
				else{
					Window.Location.replace("/classconversation/secured/ClassCommons.html?cid="+selectedCourse.getCourseID()+"&cname="+selectedCourse.getCourseName());
				}


			}

		});
		fTable.setWidget(2, 0, enter);
		fTable.getCellFormatter().addStyleName(2, 0, "floatRight");
		fTable.setWidth("400px");
		fPanel.add(fTable);
		return fPanel;
	}


	private void markAsEnrolled(final Course c){
		// Initialize the service proxy.
		if (loginServiceSvc == null) {
			loginServiceSvc = GWT.create(LoginService.class);
		}
		// Set up the callback object.
		AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {
			public void onFailure(Throwable caught) {
				caught.printStackTrace();
				Log.debug("Error when marking the course as enrolled");
			}
			public void onSuccess(Boolean enrolled) {
				if (enrolled){
					enrolledCourses.add(c);
					Window.Location.replace("/classconversation/secured/ClassCommons.html?cid="+c.getCourseID()+"&cname="+c.getCourseName());
				}
			}
		};
		loginServiceSvc.markAsEnrolled(c, uid, callback);
	}

	private boolean isEnrolled(Course c){
		boolean enrolled = false;
		for (int i=0; i< enrolledCourses.size(); i++){
			Course temp = enrolledCourses.get(i);
			if (c.getCourseID() == temp.getCourseID()){
				enrolled = true;
				break;
			}
		}
		return enrolled;

	}

	private Course getSelectedCourse(){
		Course c = allCourses.get(courseList.getSelectedIndex());
		return c;
	}

	boolean contains(ArrayList<Course> list, Course c){
		for (int i = 0; i< list.size(); i++){
			if (list.get(i).getCourseID()==(c.getCourseID())){
				return true;
			}
		}
		return false;
	}


}
